package com.zh.webcommon.common.auth;

import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 收集不需要认证的请求URI，即被@NonePermission修饰的接口方法
 *
 * @author ZH
 * @date 13:38 2021/11/4
 */
public final class CollectPermitRequestURI {

    private CollectPermitRequestURI(){}

    /**
     * 存储针对one method的权限白名单
     */
    private static final Map<String, HttpMethod> permitRequestUrisWithMethod = new HashMap<>();
    /**
     * 存储针对all method的权限白名单
     */
    private static final Set<String> permitRequestUrisAllMethod = new HashSet<>();
    /**
     * 存储针对all method的角色白名单
     */
    private static final Map<String, String[]> hasRoleRequestUrisAllMethod = new HashMap<>();

    /**
     * 加入权限白名单
     *
     * @param uriPattern
     * @param method
     */
    public static void addPermitRequestURI(String uriPattern, @Nullable HttpMethod method) {
        if (!StringUtils.hasLength(uriPattern)) return;

        if (method == null) {
            permitRequestUrisAllMethod.add(uriPattern);
        } else {
            permitRequestUrisWithMethod.putIfAbsent(uriPattern, method);
        }
    }

    /**
     * 加入角色权限白名单
     *
     * @param uriPattern
     * @param roles
     */
    public static void addHasRoleRequestURI(String uriPattern, String... roles) {
        if (!StringUtils.hasLength(uriPattern) || roles.length == 0) return;
        hasRoleRequestUrisAllMethod.putIfAbsent(uriPattern, roles);
    }

    /**
     * 获取权限白名单
     *
     * @return Set<String>
     */
    public static Set<String> getPermitRequestURI() {
        return Collections.unmodifiableSet(permitRequestUrisAllMethod);
    }

    /**
     * 获取权限白名单
     *
     * @return MultiValueMap<Key = method, Value = uris>
     */
    public static MultiValueMap<HttpMethod, String> getPermitRequestURIWithMethodScope() {
        MultiValueMap<HttpMethod, String> methodToRequestUrisMap = new LinkedMultiValueMap<>();
        permitRequestUrisWithMethod.forEach((k, v) -> {
            methodToRequestUrisMap.add(v, k);
        });
        return methodToRequestUrisMap;
    }

    /**
     * 获取角色权限白名单
     *
     * @return MultiValueMap<Key = role, Value = uris>
     */
    public static MultiValueMap<String, String> getHasRoleRequestURI() {
        MultiValueMap<String, String> roleToRequestUrisMap = new LinkedMultiValueMap<>();
        hasRoleRequestUrisAllMethod.forEach((k, v) -> {
            Arrays.stream(v).forEach(e -> roleToRequestUrisMap.add(e, k));
        });
        return roleToRequestUrisMap;
    }

}
